<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>http协议 | East'blog</title><meta name="author" content="侯玉东"><meta name="copyright" content="侯玉东"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="http协议">
<meta property="og:type" content="article">
<meta property="og:title" content="http协议">
<meta property="og:url" content="https://houyudong1989.gitee.io/blog/2024/04/12/python/6%E3%80%81http%E5%8D%8F%E8%AE%AE/index.html">
<meta property="og:site_name" content="East&#39;blog">
<meta property="og:description" content="http协议">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://houyudong1989.gitee.io/blog/img/library1.jpeg">
<meta property="article:published_time" content="2024-04-12T08:08:38.231Z">
<meta property="article:modified_time" content="2024-04-17T01:38:41.136Z">
<meta property="article:author" content="侯玉东">
<meta property="article:tag" content="http协议">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://houyudong1989.gitee.io/blog/img/library1.jpeg"><link rel="shortcut icon" href="/blog/img/head.jpg"><link rel="canonical" href="https://houyudong1989.gitee.io/blog/2024/04/12/python/6%E3%80%81http%E5%8D%8F%E8%AE%AE/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/blog/',
  algolia: undefined,
  localSearch: undefined,
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  infinitegrid: {
    js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid/dist/infinitegrid.min.js',
    buttonText: '加载更多'
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'http协议',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2024-04-17 09:38:41'
}</script><script>(win=>{
      win.saveToLocal = {
        set: (key, value, ttl) => {
          if (ttl === 0) return
          const now = Date.now()
          const expiry = now + ttl * 86400000
          const item = {
            value,
            expiry
          }
          localStorage.setItem(key, JSON.stringify(item))
        },
      
        get: key => {
          const itemStr = localStorage.getItem(key)
      
          if (!itemStr) {
            return undefined
          }
          const item = JSON.parse(itemStr)
          const now = Date.now()
      
          if (now > item.expiry) {
            localStorage.removeItem(key)
            return undefined
          }
          return item.value
        }
      }
    
      win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.src = url
        script.async = true
        script.onerror = reject
        script.onload = script.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          script.onload = script.onreadystatechange = null
          resolve()
        }

        Object.keys(attr).forEach(key => {
          script.setAttribute(key, attr[key])
        })

        document.head.appendChild(script)
      })
    
      win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
        const link = document.createElement('link')
        link.rel = 'stylesheet'
        link.href = url
        if (id) link.id = id
        link.onerror = reject
        link.onload = link.onreadystatechange = function() {
          const loadState = this.readyState
          if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
          link.onload = link.onreadystatechange = null
          resolve()
        }
        document.head.appendChild(link)
      })
    
      win.activateDarkMode = () => {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = () => {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
        if (t === 'dark') activateDarkMode()
        else if (t === 'light') activateLightMode()
      
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
      const detectApple = () => {
        if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
          document.documentElement.classList.add('apple')
        }
      }
      detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
  const $loadingBox = document.getElementById('loading-box')
  const $body = document.body
  const preloader = {
    endLoading: () => {
      $body.style.overflow = ''
      $loadingBox.classList.add('loaded')
    },
    initLoading: () => {
      $body.style.overflow = 'hidden'
      $loadingBox.classList.remove('loaded')
    }
  }

  preloader.initLoading()
  window.addEventListener('load',() => { preloader.endLoading() })

  if (true) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
  }
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/blog/img/head.jpg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">70</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">26</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/blog/link/"><i class="fa-fw fas fa-link"></i><span> 友联</span></a></div><div class="menus_item"><a class="site-page" href="/blog/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg fixed" id="page-header" style="background-image: url('/blog/img/library3.jpeg')"><nav id="nav"><span id="blog-info"><a href="/blog/" title="East'blog"><img class="site-icon" src="/blog/img/head.jpg"/><span class="site-name">East'blog</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/blog/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/blog/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/blog/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/blog/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/blog/link/"><i class="fa-fw fas fa-link"></i><span> 友联</span></a></div><div class="menus_item"><a class="site-page" href="/blog/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">http协议</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2024-04-12T08:08:38.231Z" title="发表于 2024-04-12 16:08:38">2024-04-12</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2024-04-17T01:38:41.136Z" title="更新于 2024-04-17 09:38:41">2024-04-17</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/blog/categories/python-%E7%88%AC%E8%99%AB-http/">python 爬虫 http</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="http协议"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="HTTP协议"><a href="#HTTP协议" class="headerlink" title="HTTP协议"></a>HTTP协议</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">HTTP（Hypertext Transfer Protocol）是一种用于传输超文本数据（如HTML）的应用层协议，它是万维网（World Wide Web）的基础之一。HTTP协议通常用于客户端（例如Web浏览器）和服务器之间的通信，用于请求服务器上的资源并将其传输到客户端。</span><br><span class="line"></span><br><span class="line">HTTP是一个基于TCP/IP通信协议来传递数据（HTML 文件, 图片文件, 查询结果等）。</span><br><span class="line"></span><br><span class="line">HTTP是一个属于应用层的面向对象的协议，由于其简捷、快速的方式，适用于分布式超媒体信息系统。它于1990年提出，经过几年的使用与发展，得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.1版及最新的HTTP/2，HTTP/3.0的规范化工作正在进行之中。</span><br><span class="line"></span><br><span class="line">HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后，向客户端发送响应信息。</span><br><span class="line"></span><br><span class="line">目前主要的HTTP协议版本为HTTP/1.1， HTTP/2， HTTP/3。</span><br><span class="line"></span><br><span class="line">HTTP 的 URL 是由 http:// 起始与默认使用端口 80</span><br></pre></td></tr></table></figure>

<h2 id="TCP-三次握手"><a href="#TCP-三次握手" class="headerlink" title="TCP 三次握手"></a>TCP 三次握手</h2><p><img src="/blog/6%E3%80%81http%E5%8D%8F%E8%AE%AE/1713260694727.png" alt="1713260694727"></p>
<p><img src="/blog/6%E3%80%81http%E5%8D%8F%E8%AE%AE/1713260731285.png" alt="1713260731285"></p>
<h2 id="HTTP特点"><a href="#HTTP特点" class="headerlink" title="HTTP特点"></a>HTTP特点</h2><blockquote>
<p><strong>无连接性（Connectionless）</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP是一种无连接的协议，这意味着每个请求和响应之间是相互独立的，服务器不会保存有关客户端的任何状态信息。这样的设计简化了协议和实现，并使得服务器可以更好地处理大量的请求。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>无状态性（Stateless）</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP是一种无状态的协议，服务器不会保存客户端之前的请求信息。每个请求都是独立的，服务器无法识别一个请求是来自于同一个客户端还是不同的客户端。为了实现会话管理和状态保持，通常会使用Cookie等机制。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>基于请求-响应模型</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP是基于请求-响应模型的协议。客户端发送一个HTTP请求给服务器，请求包含请求的方法（如GET、POST等）、资源的URL、HTTP版本以及可选的请求头部信息等。服务器接收到请求后，会根据请求的内容做出响应，并返回一个HTTP响应给客户端，响应包含响应的状态码、响应的头部信息以及可选的响应体（如HTML文档、图片等）。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>支持多种请求方法</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP定义了多种请求方法，常见的包括GET（获取资源）、POST（提交数据）、PUT（更新资源）、DELETE（删除资源）等。每种方法都对应着不同的操作，用于实现不同的功能。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>状态码</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP使用状态码来表示请求的处理结果，常见的状态码包括200（成功）、404（未找到）、500（服务器内部错误）等。状态码的具体含义可以根据其范围进行分析，例如2xx表示成功，3xx表示重定向，4xx表示客户端错误，5xx表示服务器错误等。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>持久连接（Persistent Connection）</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">为了减少每个请求的延迟，HTTP/1.1引入了持久连接的机制，允许客户端和服务器在一次连接中发送和接收多个请求和响应，而不需要每次请求都建立新的连接。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>安全性</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP本身是不安全的，所有的数据都是以明文形式传输的，容易被窃听和篡改。为了保证通信的安全性，通常会使用HTTPS（HTTP Secure）协议，它在HTTP上加入了SSL/TLS加密层，对通信进行加密和认证。</span><br></pre></td></tr></table></figure>

<h2 id="HTTP-状态码"><a href="#HTTP-状态码" class="headerlink" title="HTTP 状态码"></a>HTTP 状态码</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">所有 HTTP 响应状态代码都分为五个类或类别。状态码的第一个数字定义了响应的类别，而最后两个数字没有任何分类或分类作用。该标准定义了五个等级：</span><br><span class="line">    1xx 信息响应——请求已收到，继续处理</span><br><span class="line">    2xx 成功——请求被成功接收、理解和接受</span><br><span class="line">    3xx 重定向- 需要采取进一步的措施才能完成请求</span><br><span class="line">    4xx 客户端错误– 请求包含错误语法或无法完成</span><br><span class="line">    5xx 服务器错误– 服务器未能满足明显有效的请求</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>1×× 信息</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">信息响应表明请求已被接收并理解。它是在请求处理继续进行时临时发布的。它提醒客户端等待最终响应。该消息仅由状态行和可选的头字段组成，并以空行结束。</span><br><span class="line">100 Continue :继续</span><br><span class="line">101 Switching Protocols : 交换协议</span><br><span class="line">102 Processing : 处理中 (WebDAV)</span><br><span class="line">103 Early Hints : 早期提示</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>2×× 成功</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">此类状态代码表示客户端请求的操作已被接收、理解和接受。</span><br><span class="line">200 OK : 请求成功</span><br><span class="line">201 Created : 已创建</span><br><span class="line">202 Accepted : 接受</span><br><span class="line">203 Non-authoritative Information : 非权威信息</span><br><span class="line">204 No Content : 无内容</span><br><span class="line">205 Reset Content : 重置内容 -- 告诉用户代理重置发送此请求的文档</span><br><span class="line">206 Partial Content : 部分内容</span><br><span class="line">207 Multi-Status : 多状态 (WebDAV)</span><br><span class="line">208 Already Reported : 已报告 (WebDAV)</span><br><span class="line">226 IM Used : 已完成响应 (HTTP Delta encoding)</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>3×× 重定向</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">此类状态码表明客户端必须采取额外的行动来完成请求。许多这些状态代码用于URL 重定向。</span><br><span class="line">300 Multiple Choices : 多项选择 -- 该请求有多个可能的响应。用户代理或用户应该选择其中之一。</span><br><span class="line">301 Moved Permanently : 永久移动</span><br><span class="line">302 Found : 找到</span><br><span class="line">303 See Other : 查看其他</span><br><span class="line">304 Not Modified : 未修改</span><br><span class="line">305 Use Proxy : 使用代理 -- 它已被弃用。</span><br><span class="line">307 Temporary Redirect : 临时重定向</span><br><span class="line">308 Permanent Redirect: 永久重定向</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>4×× 客户端错误</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">此类状态代码适用于错误似乎是由客户端引起的情况。</span><br><span class="line">400 Bad Request : 错误请求</span><br><span class="line">401 Unauthorized : 未经授权</span><br><span class="line">402 Payment Required : 需要付款</span><br><span class="line">403 Forbidden : 禁止访问</span><br><span class="line">404 Not Found : 未找到</span><br><span class="line">405 Method Not Allowed : 方法不允许</span><br><span class="line">406 Not Acceptable : 不可接受</span><br><span class="line">407 Proxy Authentication Required : 需要代理身份验证</span><br><span class="line">408 Request Timeout : 请求超时</span><br><span class="line">409 Conflict : 存在冲突</span><br><span class="line">410 Gone : 资源已经不存在(过去存在)</span><br><span class="line">411 Length Required : 长度要求</span><br><span class="line">412 Precondition Failed : 前置条件失败</span><br><span class="line">413 Payload Too Large : 请求的实体过大</span><br><span class="line">414 Request-URI Too Long : 请求 URI 太长</span><br><span class="line">415 Unsupported Media Type : 不支持的媒体类型</span><br><span class="line">416 Requested Range Not Satisfiable : 请求的范围不满足</span><br><span class="line">417 Expectation Failed : 期望失败</span><br><span class="line">418 I&#x27;m a teapot : 我是个茶壶</span><br><span class="line">421 Misdirected Request : 错误的请求</span><br><span class="line">422 Unprocessable Entity : 无法处理的实体( WebDAV )</span><br><span class="line">423 Locked : 锁定( WebDAV )</span><br><span class="line">424 Failed Dependency : 依赖失败( WebDAV )</span><br><span class="line">425 Too Early (RFC 8470) : 太早 -- 表示服务器不愿意冒险处理可能被重放的请求</span><br><span class="line">426 Upgrade Required : 需要升级</span><br><span class="line">428 Precondition Required : 需要先决条件</span><br><span class="line">429 Too Many Requests : 请求过多</span><br><span class="line">431 Request Header Fields Too Large : 请求标头字段太大</span><br><span class="line">444 Connection Closed Without Response : 连接关闭而无响应</span><br><span class="line">451 Unavailable For Legal Reasons : 因法律原因不可用</span><br><span class="line">499 Client Closed Request : 客户端关闭请求</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>5×× 服务器错误</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">以数字“5”开头的响应状态代码表示服务器遇到错误或无法执行请求.</span><br><span class="line">500 Internal Server Error : 内部服务器错误</span><br><span class="line">501 Not Implemented : 未实施</span><br><span class="line">502 Bad Gateway : 错误网关</span><br><span class="line">503 Service Unavailable : 服务不可用</span><br><span class="line">504 Gateway Timeout : 网关超时</span><br><span class="line">505 HTTP Version Not Supported : 不支持的 HTTP 版本</span><br><span class="line">506 Variant Also Negotiates : 变体也协商 -- 请求的透明内容协商导致循环引用.</span><br><span class="line">507 Insufficient Storage : 存储空间不足 ( WebDAV )</span><br><span class="line">508 Loop Detected : 检测到环路 ( WebDAV ) -- 服务器在处理请求时检测到无限循环</span><br><span class="line">510 Not Extended : 未扩展 -- 服务器需要对请求进行进一步扩展才能完成它</span><br><span class="line">511 Network Authentication Required : 需要网络身份验证</span><br><span class="line">599 Network Connect Timeout Error : 网络连接超时错误</span><br></pre></td></tr></table></figure>

<h2 id="HTTP-content-Type"><a href="#HTTP-content-Type" class="headerlink" title="HTTP content-Type"></a>HTTP content-Type</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Content-Type，内容类型，一般是指网页中存在的Content-Type，用于定义网络文件的类型和网页的编码，决定浏览器将以什么形式、什么编码读取这个文件，这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。</span><br></pre></td></tr></table></figure>

<blockquote>
<p>常见的媒体格式类型如下：</p>
</blockquote>
<ul>
<li>text&#x2F;html ： HTML格式</li>
<li>text&#x2F;plain ：纯文本格式</li>
<li>text&#x2F;xml ： XML格式</li>
<li>image&#x2F;gif ：gif图片格式</li>
<li>image&#x2F;jpeg ：jpg图片格式</li>
<li>image&#x2F;png：png图片格式</li>
</ul>
<blockquote>
<p>以application开头的媒体格式类型：</p>
</blockquote>
<ul>
<li>application&#x2F;xhtml+xml ：XHTML格式</li>
<li>application&#x2F;xml： XML数据格式</li>
<li>application&#x2F;atom+xml ：Atom XML聚合格式</li>
<li>application&#x2F;json： JSON数据格式</li>
<li>application&#x2F;pdf：pdf格式</li>
<li>application&#x2F;msword ： Word文档格式</li>
<li>application&#x2F;octet-stream ： 二进制流数据（如常见的文件下载）</li>
<li>application&#x2F;x-www-form-urlencoded ： <code>&lt;form encType=””&gt;</code>中默认的encType，form表单数据被编码为key&#x2F;value格式发送到服务器（表单默认的提交数据的格式）</li>
</ul>
<blockquote>
<p>另外一种常见的媒体格式是上传文件之时使用的：</p>
</blockquote>
<ul>
<li>multipart&#x2F;form-data ： 需要在表单中进行文件上传时，就需要使用该格式</li>
</ul>
<h2 id="MIME类型"><a href="#MIME类型" class="headerlink" title="MIME类型"></a>MIME类型</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准，用来表示文档、文件或字节流的性质和格式。</span><br><span class="line"></span><br><span class="line">MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。</span><br><span class="line"></span><br><span class="line">浏览器通常使用 MIME 类型（而不是文件扩展名）来确定如何处理URL，因此 We b服务器在响应头中添加正确的 MIME 类型非常重要。如果配置不正确，浏览器可能会无法解析文件内容，网站将无法正常工作，并且下载的文件也会被错误处理。 </span><br><span class="line"></span><br><span class="line">MIME 的组成结构非常简单，由类型与子类型两个字符串中间用 / 分隔而组成，不允许有空格。type 表示可以被分多个子类的独立类别，subtype 表示细分后的每个类型。</span><br><span class="line"></span><br><span class="line">MIME类型对大小写不敏感，但是传统写法都是小写。</span><br><span class="line"></span><br><span class="line">两种主要的 MIME 类型在默认类型中扮演了重要的角色：</span><br><span class="line"></span><br><span class="line">text/plain 表示文本文件的默认值。</span><br><span class="line">application/octet-stream 表示所有其他情况的默认值。 </span><br></pre></td></tr></table></figure>

<blockquote>
<p>常见的 MIME 类型</p>
</blockquote>
<ul>
<li>超文本标记语言文本 .html、.html：text&#x2F;html</li>
<li>普通文本 .txt： text&#x2F;plain</li>
<li>RTF 文本 .rtf： application&#x2F;rtf</li>
<li>GIF 图形 .gif： image&#x2F;gif</li>
<li>JPEG 图形 .jpeg、.jpg： image&#x2F;jpeg</li>
<li>au 声音文件 .au： audio&#x2F;basic</li>
<li>MIDI 音乐文件 mid、.midi： audio&#x2F;midi、audio&#x2F;x-midi</li>
<li>RealAudio 音乐文件 .ra、.ram： audio&#x2F;x-pn-realaudio</li>
<li>MPEG 文件 .mpg、.mpeg： video&#x2F;mpeg</li>
<li>AVI 文件 .avi： video&#x2F;x-msvideo</li>
<li>GZIP 文件 .gz： application&#x2F;x-gzip</li>
<li>TAR 文件 .tar： application&#x2F;x-tar</li>
</ul>
<table>
<thead>
<tr>
<th>类型</th>
<th>描述</th>
<th>典型示例</th>
</tr>
</thead>
<tbody><tr>
<td>text</td>
<td>表明文件是普通文本，理论上是人类可读</td>
<td>text&#x2F;plain, text&#x2F;html, text&#x2F;css, text&#x2F;javascript</td>
</tr>
<tr>
<td>image</td>
<td>表明是某种图像。不包括视频，但是动态图（比如动态gif）也使用image类型</td>
<td>image&#x2F;gif, image&#x2F;png, image&#x2F;jpeg, image&#x2F;bmp, image&#x2F;webp, image&#x2F;x-icon, image&#x2F;vnd.microsoft.icon</td>
</tr>
<tr>
<td>audio</td>
<td>表明是某种音频文件</td>
<td>audio&#x2F;midi, audio&#x2F;mpeg, audio&#x2F;webm, audio&#x2F;ogg, audio&#x2F;wav</td>
</tr>
<tr>
<td>video</td>
<td>表明是某种视频文件</td>
<td>video&#x2F;webm, video&#x2F;ogg</td>
</tr>
<tr>
<td>application</td>
<td>表明是某种二进制数据</td>
<td>application&#x2F;octet-stream, application&#x2F;pkcs12, application&#x2F;vnd.mspowerpoint, application&#x2F;xhtml+xml, application&#x2F;xml, application&#x2F;pdf</td>
</tr>
</tbody></table>
<p>1</p>
<h2 id="HTTP请求方法"><a href="#HTTP请求方法" class="headerlink" title="HTTP请求方法"></a>HTTP请求方法</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">根据HTTP标准，HTTP请求可以使用多种请求方法。</span><br><span class="line">HTTP1.0定义了三种请求方法： GET，POST 和 HEAD方法。</span><br><span class="line"></span><br><span class="line">HTTP1.1新增了五种请求方法：OPTIONS，PUT，DELETE，TRACE 和 CONNECT 方法。</span><br></pre></td></tr></table></figure>

<p><img src="/blog/6%E3%80%81http%E5%8D%8F%E8%AE%AE/1713258107317.png" alt="1713258107317"></p>
<h2 id="HTTP-请求消息"><a href="#HTTP-请求消息" class="headerlink" title="HTTP 请求消息"></a>HTTP 请求消息</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一个HTTP请求报文（也称请求消息）由请求行（request line）、请求头（header）、空行和请求数据(也称请求体)4个部分组成，下图给出了请求报文的一般格式。</span><br></pre></td></tr></table></figure>

<p><img src="/blog/6%E3%80%81http%E5%8D%8F%E8%AE%AE/1713257764588.png" alt="1713257764588"></p>
<blockquote>
<p><strong>请求行</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">请求行（也称请求起始行）由请求方法字段、URL字段和HTTP协议版本字段3个字段组成，它们用空格分隔。</span><br><span class="line">请求行格式如下：Method空格Request-URI空格HTTP-Version CRLF</span><br><span class="line">- Method  表示请求方法；</span><br><span class="line">- Request-URl 表示一个统一资源标识符；</span><br><span class="line">- HTTP-Version 表示请求的 HTTP 协议版本；</span><br><span class="line">- CRLF 表示回车和换行；</span><br><span class="line"></span><br><span class="line">示例：</span><br><span class="line">    GET /index.html HTTP/1.1</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>请求头</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">请求头部由关键字/值对组成，每行一对，关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息</span><br><span class="line"></span><br><span class="line">在HTTP/1.1协议中，所有的请求头，除post外，都是可选的。</span><br><span class="line"></span><br><span class="line">请求头是以key: value的形式现示的。每一个报头域（报头域包括请求头和响应头）都是由名字+”：”+空格+值组成，消息报头域的名字是大小写无关的。</span><br><span class="line"></span><br><span class="line">请求头里保存的是请求的属性， 冒号分割的键值对；每组属性之间使用\r\n分隔；遇到空行表示请求头部分结束。(windows下使用\n,linux下使用\r\n)</span><br></pre></td></tr></table></figure>

<blockquote>
<blockquote>
<p>示例</p>
</blockquote>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Host: www.example.com</span><br><span class="line">User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0</span><br><span class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8</span><br><span class="line">Accept-Language: en-US,en;q=0.5</span><br><span class="line">Accept-Encoding: gzip, deflate, br</span><br><span class="line">Connection: keep-alive</span><br><span class="line">Referer: https://www.google.com/</span><br><span class="line">Cookie: sessionId=abc123; userId=123456</span><br><span class="line">Content-Type: application/json</span><br><span class="line">Content-Length: 123</span><br></pre></td></tr></table></figure>

<blockquote>
<blockquote>
<p>解释</p>
</blockquote>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Host：指定了请求的主机名。</span><br><span class="line">User-Agent：包含了发起请求的用户代理（User Agent）信息，通常包含了浏览器的相关信息。</span><br><span class="line">Accept：指定了客户端能够接受的响应内容类型，这里表示客户端可以接受HTML、XML等类型的内容。</span><br><span class="line">Accept-Language：指定了客户端能够接受的语言类型。</span><br><span class="line">Accept-Encoding：指定了客户端能够接受的内容编码类型，这里表示客户端可以接受gzip、deflate和br（Brotli）编码的内容。</span><br><span class="line">Connection：指定了连接的持久性，这里表示客户端希望保持与服务器的连接持久性。</span><br><span class="line">Referer：当前页面是从哪个页面跳转过来的。</span><br><span class="line">Cookie：包含了客户端发送给服务器的Cookie信息，用于会话管理和状态保持。</span><br><span class="line">Content-Type：指定了请求体的MIME类型，这里是application/json。</span><br><span class="line">Content-Length：指定了请求体的长度，单位为字节。</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<blockquote>
<p>空行</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一个空行指示所有关于请求的元数据已经发送完毕，即空行标志着请求头的结束，也标志着请求体的开始。空行可以用\r\n书写。</span><br></pre></td></tr></table></figure>

<h2 id="HTTP-响应消息"><a href="#HTTP-响应消息" class="headerlink" title="HTTP 响应消息"></a>HTTP 响应消息</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">HTTP响应消息是服务器返回给客户端的消息，它包含了服务器处理请求的结果以及相关的元数据。一个标准的HTTP响应消息由以下几部分组成：</span><br><span class="line"></span><br><span class="line">状态行（Status Line）：包含了HTTP协议版本、状态码和对应的状态消息。例如：HTTP/1.1 200 OK。</span><br><span class="line"></span><br><span class="line">响应头部（Response Headers）：包含了关于响应的元数据信息，例如服务器类型、日期、内容类型等。响应头部是以键值对的形式表示的。</span><br><span class="line"></span><br><span class="line">空行：用于分隔响应头部和响应体的空行。</span><br><span class="line"></span><br><span class="line">响应体（Response Body）：包含了实际的响应内容，可以是HTML文档、JSON数据、图片等。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>状态行</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">状态行（status line）通过提供一个状态码来说明所请求的资源情况。</span><br><span class="line"></span><br><span class="line">状态行包括：协议版本，状态码，[状态码说明]，状态行格式如下：</span><br><span class="line"></span><br><span class="line">HTTP-Version空格Status-Code空格Reason-Phrase CRLF  </span><br><span class="line"></span><br><span class="line">HTTP-Version表示服务器HTTP协议的版本，例如为HTTP/1.1；</span><br><span class="line">Status-Code表示服务器发回的响应状态代码，例如200；</span><br><span class="line">Reason-Phrase表示状态代码的文本描述，解释Status-Code的具体原因。</span><br><span class="line"></span><br><span class="line">示例：</span><br><span class="line">    HTTP/1.1 200 OK </span><br><span class="line"> </span><br></pre></td></tr></table></figure>

<p>1</p>
<blockquote>
<p><strong>响应头</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">包含了Date、Server、Content-Type和Content-Length等字段，分别表示响应的日期、服务器类型、内容类型和内容长度。</span><br><span class="line">Date: Fri, 16 Apr 2024 09:30:00 GMT</span><br><span class="line">Server: Apache/2.4.38 (Ubuntu)</span><br><span class="line">Content-Type: text/html; charset=UTF-8</span><br><span class="line">Content-Length: 1234</span><br></pre></td></tr></table></figure>

<table>
<thead>
<tr>
<th><strong>Allow</strong></th>
<th><strong>服务器支持哪些请求方法（如GET、POST等）。</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>Content-Encoding</strong></td>
<td><strong>文档的编码（Encode）方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩，但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此，Servlet应该通过查看Accept-Encoding头（即request.getHeader(“Accept-Encoding”)）检查浏览器是否支持gzip，为支持gzip的浏览器返回经gzip压缩的HTML页面，为其他浏览器返回普通页面。</strong></td>
</tr>
<tr>
<td><strong>Content-Length</strong></td>
<td><strong>表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势，可以把输出文档写入 ByteArrayOutputStream，完成后查看其大小，然后把该值放入Content-Length头，最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。</strong></td>
</tr>
<tr>
<td><strong>Content-Type</strong></td>
<td><strong>表示后面的文档属于什么MIME类型。Servlet默认为text&#x2F;plain，但通常需要显式地指定为text&#x2F;html。由于经常要设置Content-Type，因此HttpServletResponse提供了一个专用的方法setContentType。</strong></td>
</tr>
<tr>
<td><strong>Date</strong></td>
<td><strong>当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。</strong></td>
</tr>
<tr>
<td><strong>Expires</strong></td>
<td><strong>应该在什么时候认为文档已经过期，从而不再缓存它？</strong></td>
</tr>
<tr>
<td><strong>Last-Modified</strong></td>
<td><strong>文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期，该请求将被视为一个条件GET，只有改动时间迟于指定时间的文档才会返回，否则返回一个304（Not Modified）状态。Last-Modified也可用setDateHeader方法来设置。</strong></td>
</tr>
<tr>
<td><strong>Location</strong></td>
<td><strong>表示客户应当到哪里去提取文档。Location通常不是直接设置的，而是通过HttpServletResponse的sendRedirect方法，该方法同时设置状态代码为302。</strong></td>
</tr>
<tr>
<td><strong>Refresh</strong></td>
<td>表示浏览器应该在多少时间之后刷新文档，以秒计。除了刷新当前文档之外，你还可以通过setHeader(“Refresh”, “5; URL&#x3D;<a target="_blank" rel="noopener" href="http://host/path%22)%E8%AE%A9%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AF%BB%E5%8F%96%E6%8C%87%E5%AE%9A%E7%9A%84%E9%A1%B5%E9%9D%A2%E3%80%82%60%60%E6%B3%A8%E6%84%8F%E8%BF%99%E7%A7%8D%E5%8A%9F%E8%83%BD%E9%80%9A%E5%B8%B8%E6%98%AF%E9%80%9A%E8%BF%87%E8%AE%BE%E7%BD%AEHTML%E9%A1%B5%E9%9D%A2HEAD%E5%8C%BA%E7%9A%84%EF%BC%9CMETA">http://host/path&quot;)让浏览器读取指定的页面。``注意这种功能通常是通过设置HTML页面HEAD区的＜META</a> HTTP-EQUIV&#x3D;”Refresh” CONTENT&#x3D;”5;URL&#x3D;<a target="_blank" rel="noopener" href="http://host/path%22%EF%BC%9E%E5%AE%9E%E7%8E%B0%EF%BC%8C%E8%BF%99%E6%98%AF%E5%9B%A0%E4%B8%BA%EF%BC%8C%E8%87%AA%E5%8A%A8%E5%88%B7%E6%96%B0%E6%88%96%E9%87%8D%E5%AE%9A%E5%90%91%E5%AF%B9%E4%BA%8E%E9%82%A3%E4%BA%9B%E4%B8%8D%E8%83%BD%E4%BD%BF%E7%94%A8CGI%E6%88%96Servlet%E7%9A%84HTML%E7%BC%96%E5%86%99%E8%80%85%E5%8D%81%E5%88%86%E9%87%8D%E8%A6%81%E3%80%82%E4%BD%86%E6%98%AF%EF%BC%8C%E5%AF%B9%E4%BA%8EServlet%E6%9D%A5%E8%AF%B4%EF%BC%8C%E7%9B%B4%E6%8E%A5%E8%AE%BE%E7%BD%AERefresh%E5%A4%B4%E6%9B%B4%E5%8A%A0%E6%96%B9%E4%BE%BF%E3%80%82%60%60%E6%B3%A8%E6%84%8FRefresh%E7%9A%84%E6%84%8F%E4%B9%89%E6%98%AF%22N%E7%A7%92%E4%B9%8B%E5%90%8E%E5%88%B7%E6%96%B0%E6%9C%AC%E9%A1%B5%E9%9D%A2%E6%88%96%E8%AE%BF%E9%97%AE%E6%8C%87%E5%AE%9A%E9%A1%B5%E9%9D%A2%22%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%22%E6%AF%8F%E9%9A%94N%E7%A7%92%E5%88%B7%E6%96%B0%E6%9C%AC%E9%A1%B5%E9%9D%A2%E6%88%96%E8%AE%BF%E9%97%AE%E6%8C%87%E5%AE%9A%E9%A1%B5%E9%9D%A2%22%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8C%E8%BF%9E%E7%BB%AD%E5%88%B7%E6%96%B0%E8%A6%81%E6%B1%82%E6%AF%8F%E6%AC%A1%E9%83%BD%E5%8F%91%E9%80%81%E4%B8%80%E4%B8%AARefresh%E5%A4%B4%EF%BC%8C%E8%80%8C%E5%8F%91%E9%80%81204%E7%8A%B6%E6%80%81%E4%BB%A3%E7%A0%81%E5%88%99%E5%8F%AF%E4%BB%A5%E9%98%BB%E6%AD%A2%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BB%A7%E7%BB%AD%E5%88%B7%E6%96%B0%EF%BC%8C%E4%B8%8D%E7%AE%A1%E6%98%AF%E4%BD%BF%E7%94%A8Refresh%E5%A4%B4%E8%BF%98%E6%98%AF%EF%BC%9CMETA">http://host/path&quot;＞实现，这是因为，自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是，对于Servlet来说，直接设置Refresh头更加方便。``注意Refresh的意义是&quot;N秒之后刷新本页面或访问指定页面&quot;，而不是&quot;每隔N秒刷新本页面或访问指定页面&quot;。因此，连续刷新要求每次都发送一个Refresh头，而发送204状态代码则可以阻止浏览器继续刷新，不管是使用Refresh头还是＜META</a> HTTP-EQUIV&#x3D;”Refresh” …＞。&#96;&#96;注意Refresh头不属于HTTP 1.1正式规范的一部分，而是一个扩展，但Netscape和IE都支持它。</td>
</tr>
<tr>
<td><strong>Server</strong></td>
<td><strong>服务器名字。Servlet一般不设置这个值，而是由Web服务器自己设置。</strong></td>
</tr>
<tr>
<td><strong>Set-Cookie</strong></td>
<td><strong>设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …)，而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。</strong></td>
</tr>
<tr>
<td><strong>WWW-Authenticate</strong></td>
<td>客户应该在Authorization头中提供什么类型的授权信息？在包含401（Unauthorized）状态行的应答中这个头是必需的。例如，response.setHeader(“WWW-Authenticate”, “BASIC realm&#x3D;＼”executives＼””)。&#96;&#96;注意Servlet一般不进行这方面的处理，而是让Web服务器的专门机制来控制受密码保护页面的访问（例如.htaccess）。</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>空行</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">空行标志着请求头的结束，也标志着请求体的开始。空行可以用\r\n书写。</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>响应体</strong></p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">响应正文也称响应体（Body）。空行后面的内容都是Body。 Body允许为空字符串。 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度； 如果服务器返回了一个html页面，那么html页面内容就是在body中。</span><br></pre></td></tr></table></figure>

<blockquote>
<p>完整响应内容</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">HTTP/1.1 200 OK</span><br><span class="line">Date: Fri, 16 Apr 2024 09:30:00 GMT</span><br><span class="line">Server: Apache/2.4.38 (Ubuntu)</span><br><span class="line">Content-Type: text/html; charset=UTF-8</span><br><span class="line">Content-Length: 1234</span><br><span class="line"></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Example Page<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Hello, World!<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span>&gt;</span>This is an example page.<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h1 id="HTTPS"><a href="#HTTPS" class="headerlink" title="HTTPS"></a>HTTPS</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">HTTPS 协议是 HyperText Transfer Protocol Secure（超文本传输安全协议）的缩写，是一种通过计算机网络进行安全通信的传输协议。</span><br><span class="line"></span><br><span class="line">HTTPS 经由 HTTP 进行通信，但利用 SSL/TLS 来加密数据包，HTTPS 开发的主要目的，是提供对网站服务器的身份认证，保护交换资料的隐私与完整性。</span><br><span class="line"></span><br><span class="line">HTTPS 的 URL 由 https:// 起始与默认使用端口443。</span><br></pre></td></tr></table></figure>

<h2 id="HTTPS工作原理"><a href="#HTTPS工作原理" class="headerlink" title="HTTPS工作原理"></a>HTTPS工作原理</h2><p><img src="/blog/6%E3%80%81http%E5%8D%8F%E8%AE%AE/1713260758822.png" alt="1713260758822"></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">1、客户端发起 HTTPS 请求</span><br><span class="line"></span><br><span class="line">用户在浏览器里输入一个 https 网址，然后连接到 server 的 443 端口。</span><br><span class="line"></span><br><span class="line">2、服务端的配置</span><br><span class="line"></span><br><span class="line">采用 HTTPS 协议的服务器必须要有一套数字证书，可以自己制作，也可以向组织申请，区别就是自己颁发的证书需要客户端验证通过，才可以继续访问，而使用受信任的公司申请的证书则不会弹出提示页面(startssl 就是个不错的选择，有 1 年的免费服务)。</span><br><span class="line"></span><br><span class="line">这套证书其实就是一对公钥和私钥，如果对公钥和私钥不太理解，可以想象成一把钥匙和一个锁头，只是全世界只有你一个人有这把钥匙，你可以把锁头给别人，别人可以用这个锁把重要的东西锁起来，然后发给你，因为只有你一个人有这把钥匙，所以只有你才能看到被这把锁锁起来的东西。</span><br><span class="line"></span><br><span class="line">3、传送证书</span><br><span class="line"></span><br><span class="line">这个证书其实就是公钥，只是包含了很多信息，如证书的颁发机构，过期时间等等。</span><br><span class="line"></span><br><span class="line">4、客户端解析证书</span><br><span class="line"></span><br><span class="line">这部分工作是有客户端的TLS来完成的，首先会验证公钥是否有效，比如颁发机构，过期时间等等，如果发现异常，则会弹出一个警告框，提示证书存在问题。</span><br><span class="line"></span><br><span class="line">如果证书没有问题，那么就生成一个随机值，然后用证书对该随机值进行加密，就好像上面说的，把随机值用锁头锁起来，这样除非有钥匙，不然看不到被锁住的内容。</span><br><span class="line"></span><br><span class="line">5、传送加密信息</span><br><span class="line"></span><br><span class="line">这部分传送的是用证书加密后的随机值，目的就是让服务端得到这个随机值，以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。</span><br><span class="line"></span><br><span class="line">6、服务端解密信息</span><br><span class="line"></span><br><span class="line">服务端用私钥解密后，得到了客户端传过来的随机值(对称秘钥)，然后把内容通过该值进行对称加密，所谓对称加密就是，将信息和私钥通过某种算法混合在一起，这样除非知道私钥，不然无法获取内容，而正好客户端和服务端都知道这个私钥，所以只要加密算法够彪悍，私钥够复杂，数据就够安全。</span><br><span class="line"></span><br><span class="line">7、传输加密后的信息</span><br><span class="line"></span><br><span class="line">这部分信息是服务段用私钥加密后的信息，可以在客户端被还原。</span><br><span class="line"></span><br><span class="line">8、客户端解密信息</span><br><span class="line"></span><br><span class="line">客户端用之前生成的私钥解密服务段传过来的信息，于是获取了解密后的内容，整个过程第三方即使监听到了数据，也束手无策。</span><br></pre></td></tr></table></figure>

<h1 id="HTTP-与-HTTPS-区别"><a href="#HTTP-与-HTTPS-区别" class="headerlink" title="HTTP 与 HTTPS 区别"></a>HTTP 与 HTTPS 区别</h1><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">* HTTP 明文传输，数据都是未加密的，安全性较差，HTTPS（SSL+HTTP） 数据传输过程是加密的，安全性较好。</span><br><span class="line">* 使用 HTTPS 协议需要到 CA（Certificate Authority，数字证书认证机构） 申请证书，一般免费证书较少，因而需要一定费用。证书颁发机构如：Symantec、Comodo、GoDaddy 和 GlobalSign 等。</span><br><span class="line">* HTTP 页面响应速度比 HTTPS 快，主要是因为 HTTP 使用 TCP 三次握手建立连接，客户端和服务器需要交换 3 个包，而 HTTPS除了 TCP 的三个包，还要加上 ssl 握手需要的 9 个包，所以一共是 12 个包。</span><br><span class="line">* http 和 https 使用的是完全不同的连接方式，用的端口也不一样，前者是 80，后者是 443。</span><br><span class="line">* HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议，所以，要比较 HTTPS 比 HTTP 要更耗费服务器资源。</span><br></pre></td></tr></table></figure>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://houyudong1989.gitee.io/blog">侯玉东</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://houyudong1989.gitee.io/blog/2024/04/12/python/6%E3%80%81http%E5%8D%8F%E8%AE%AE/">https://houyudong1989.gitee.io/blog/2024/04/12/python/6%E3%80%81http%E5%8D%8F%E8%AE%AE/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://houyudong1989.gitee.io/blog" target="_blank">East'blog</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/blog/tags/http%E5%8D%8F%E8%AE%AE/">http协议</a></div><div class="post_share"><div class="social-share" data-image="/blog/img/library1.jpeg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/blog/2024/04/17/python/8%E3%80%81cookie%E5%92%8Csession/" title="cookie和session"><img class="cover" src="/blog/img/library1.jpeg" onerror="onerror=null;src='/blog/img/friend_404.gif'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">cookie和session</div></div></a></div><div class="next-post pull-right"><a href="/blog/2024/04/12/python/5%E3%80%81%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/" title="加密算法"><img class="cover" src="/blog/img/library1.jpeg" onerror="onerror=null;src='/blog/img/friend_404.gif'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">加密算法</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/blog/img/head.jpg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">侯玉东</div><div class="author-info__description">生命不息，奋斗不止</div></div><div class="card-info-data site-data is-center"><a href="/blog/archives/"><div class="headline">文章</div><div class="length-num">70</div></a><a href="/blog/tags/"><div class="headline">标签</div><div class="length-num">26</div></a><a href="/blog/categories/"><div class="headline">分类</div><div class="length-num">18</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://gitee.com/houyudong1989"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://gitee.com/houyudong1989" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:420098321@qq.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到我的博客！！！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#HTTP%E5%8D%8F%E8%AE%AE"><span class="toc-number">1.</span> <span class="toc-text">HTTP协议</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#TCP-%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B"><span class="toc-number">1.1.</span> <span class="toc-text">TCP 三次握手</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP%E7%89%B9%E7%82%B9"><span class="toc-number">1.2.</span> <span class="toc-text">HTTP特点</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP-%E7%8A%B6%E6%80%81%E7%A0%81"><span class="toc-number">1.3.</span> <span class="toc-text">HTTP 状态码</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP-content-Type"><span class="toc-number">1.4.</span> <span class="toc-text">HTTP content-Type</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#MIME%E7%B1%BB%E5%9E%8B"><span class="toc-number">1.5.</span> <span class="toc-text">MIME类型</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP%E8%AF%B7%E6%B1%82%E6%96%B9%E6%B3%95"><span class="toc-number">1.6.</span> <span class="toc-text">HTTP请求方法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP-%E8%AF%B7%E6%B1%82%E6%B6%88%E6%81%AF"><span class="toc-number">1.7.</span> <span class="toc-text">HTTP 请求消息</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTP-%E5%93%8D%E5%BA%94%E6%B6%88%E6%81%AF"><span class="toc-number">1.8.</span> <span class="toc-text">HTTP 响应消息</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#HTTPS"><span class="toc-number">2.</span> <span class="toc-text">HTTPS</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#HTTPS%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"><span class="toc-number">2.1.</span> <span class="toc-text">HTTPS工作原理</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#HTTP-%E4%B8%8E-HTTPS-%E5%8C%BA%E5%88%AB"><span class="toc-number">3.</span> <span class="toc-text">HTTP 与 HTTPS 区别</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/06/c++/5%E3%80%81%E5%AD%97%E7%AC%A6%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2/" title="字符和字符串"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="字符和字符串"/></a><div class="content"><a class="title" href="/blog/2024/05/06/c++/5%E3%80%81%E5%AD%97%E7%AC%A6%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2/" title="字符和字符串">字符和字符串</a><time datetime="2024-05-06T11:15:27.280Z" title="发表于 2024-05-06 19:15:27">2024-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/06/c++/4%E3%80%81%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88/" title="指针和函数指针"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="指针和函数指针"/></a><div class="content"><a class="title" href="/blog/2024/05/06/c++/4%E3%80%81%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88/" title="指针和函数指针">指针和函数指针</a><time datetime="2024-05-06T11:14:29.047Z" title="发表于 2024-05-06 19:14:29">2024-05-06</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/05/05/python/7%E3%80%81m3u8%E8%A7%86%E9%A2%91%E6%A0%BC%E5%BC%8F/" title="m3u8格式"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="m3u8格式"/></a><div class="content"><a class="title" href="/blog/2024/05/05/python/7%E3%80%81m3u8%E8%A7%86%E9%A2%91%E6%A0%BC%E5%BC%8F/" title="m3u8格式">m3u8格式</a><time datetime="2024-05-05T01:43:26.865Z" title="发表于 2024-05-05 09:43:26">2024-05-05</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/04/30/android/charles%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E6%8A%93%E5%8C%85/" title="charles 抓包"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="charles 抓包"/></a><div class="content"><a class="title" href="/blog/2024/04/30/android/charles%E5%AE%89%E5%8D%93%E6%89%8B%E6%9C%BA%E6%8A%93%E5%8C%85/" title="charles 抓包">charles 抓包</a><time datetime="2024-04-30T06:49:29.279Z" title="发表于 2024-04-30 14:49:29">2024-04-30</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/blog/2024/04/26/python/13%E3%80%81playwright/" title="playwright"><img src="/blog/img/library1.jpeg" onerror="this.onerror=null;this.src='/blog/img/friend_404.gif'" alt="playwright"/></a><div class="content"><a class="title" href="/blog/2024/04/26/python/13%E3%80%81playwright/" title="playwright">playwright</a><time datetime="2024-04-26T07:30:36.069Z" title="发表于 2024-04-26 15:30:36">2024-04-26</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2024 By 侯玉东</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/blog/js/utils.js"></script><script src="/blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><div class="js-pjax"></div><div class="aplayer no-destroy" data-id="8873950678" data-server="netease" data-type="playlist" data-fixed="true" data-autoplay="true"> </div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="false"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-fluttering-ribbon.min.js"></script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/click-heart.min.js" async="async" mobile="false"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:send', function () {

  // removeEventListener
  btf.removeGlobalFnEvent('pjax')
  btf.removeGlobalFnEvent('themeChange')

  document.getElementById('rightside').classList.remove('rightside-show')
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  //reset readmode
  const $bodyClassList = document.body.classList
  $bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode')

  typeof disqusjs === 'object' && disqusjs.destroy()
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  document.querySelectorAll('script[data-pjax]').forEach(item => {
    const newScript = document.createElement('script')
    const content = item.text || item.textContent || item.innerHTML || ""
    Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
    newScript.appendChild(document.createTextNode(content))
    item.parentNode.replaceChild(newScript, item)
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof panguInit === 'function' && panguInit()

  // google analytics
  typeof gtag === 'function' && gtag('config', '', {'page_path': window.location.pathname});

  // baidu analytics
  typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()
})

document.addEventListener('pjax:error', e => {
  if (e.request.status === 404) {
    pjax.loadUrl('/blog/404.html')
  }
})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>